package com.example.lhsama.security;

import com.example.lhsama.service.PermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @Date: 2021年09月19日 22:12
 * @Author: LHSAMA
 */
@Component
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {

    @Autowired
    private PermissionService permissionService;

    //AntPathMatcher可以进行url匹配
    private final static AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();

    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        //object 中包含用户请求的request 信息
        HttpServletRequest request = ((FilterInvocation) o).getHttpRequest();
        String uri = request.getRequestURI();
        // 忽略指定的url
        Set<String> permitSet = permitAll();

        List<ConfigAttribute> attributes = new ArrayList();
        if (!permitSet.isEmpty()) {
            for (String matcher : permitSet) {
                // 如果当前url和需要忽略的url匹配上就直接返回null，直接放行
                if (ANT_PATH_MATCHER.match(matcher, uri)) {

                    return null;
                }
            }
        }

        List<String> roleNameList = permissionService.selectRoleNamesByURI(uri); // 查出资源所需要的角色
        if(roleNameList!=null&&roleNameList.size()!=0){

            for(String roleName:roleNameList){
                attributes.add(new SecurityConfig(roleName));
            }
            return attributes;
        }
        attributes.add(new SecurityConfig("user"));
        return attributes;

    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }

    private Set<String> permitAll() {
        Set<String> set = new HashSet<>();
        set.add("/css/**");
        set.add("/fonts/**");
        set.add("/images/**");
        set.add("/js/**");
        set.add("/templates/error/**");
        set.add("/login.html");
        return set;
    }
}
